// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import {I18n, Logger} from "@aws-amplify/core";
import {API} from '@aws-amplify/api';
import {API_NAME} from '../util/Utils';
import {useEffect, useState} from 'react';
import {Link} from 'react-router-dom';
import PageTitleBar from '../components/Shared/PageTitleBar';
import Footer from '../components/Shared/Footer';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Card from 'react-bootstrap/Card';
import Table from 'react-bootstrap/Table';
import Button from 'react-bootstrap/Button';
import Alert from 'react-bootstrap/Alert';
import {IDevice, IPageProps} from '../components/Shared/Interfaces';
import Form from "react-bootstrap/Form";
import Pagination from 'react-bootstrap/Pagination';

export default function Devices(props: IPageProps): JSX.Element {
  const logger = new Logger("Devices");
  const [total, setTotal] = useState<number>(50)
  const [pageActive, setPageActive] = useState<number>(1)
  const [searchStatus, setSearchStatus] = useState<string>('hot')
  const [devices, setDevices] = useState<IDevice[]>([
    {
      key: '1',
      thingName: 'aaa',
      temperature: '36',
      thingTypeName: 'aaa',
      thingArn: 'aaa',
      status: 'aaa',
      version: 1
    },
    {
      key: '2',
      thingName: 'bbb',
      temperature: '36',
      thingTypeName: 'bbb',
      thingArn: 'bbb',
      status: 'bbb',
      version: 1
    }
  ]);
  const [showAlert, setShowAlert] = useState(false);

  const handleSubmit = async (event: any) => {
    const form = event.currentTarget;
    event.preventDefault();
    try {
      const results = await API.get(API_NAME, '/devices',{queryStringParameters:{status:{searchStatus}}});//  分页需要传递当前页码pageNumber
      setDevices([...results]);
      // 如果做分页，接口需要返回数据总条数total,当前页码pageNumber
    } catch (err) {
      logger.error(I18n.get("device.get.error"), err)
      throw err
    }

  }

  /**
   * retrieves devices and sets to state
   */
  const loadDevices = async () => {
    try {
      const results = await API.get(API_NAME, '/devices',{});
      setDevices([...results]);
    } catch (err) {
      logger.error(I18n.get("device.get.error"), err)
      throw err
    }
  }

  /**
   * React useEffect hook
   * retrieves the devices from dynamodb
   */
  useEffect(() => {
    loadDevices();
  }, []);

  /** React useEffect hook
   * sets showAlert on devices changes
   */
  useEffect(() => {
    setShowAlert(devices.length === 0);
  }, [devices])

  /**
   * Populates a table row for each device
   * @returns table row per device
   */
  const displayDevices = () => {
    if (devices) {
      return (devices.map((device, i) => (
          <tr key={i}>
            <td></td>
            <td>{device.thingName}</td>
            <td>{device.status}</td>
            <td>{device.temperature}</td>
            <td>
              <Link
                to={{
                  pathname: `/devices/modify/${device.thingName}`
                }}
              >
                <Button className="button-theme" size="sm">
                  <i className="bi bi-pencil-fill"/> {I18n.get("modify")}
                </Button>
              </Link>
              <Link
                to={{
                  pathname: `/devices/${device.thingName}`
                }}
                style={{ marginLeft: '10px' }}
              >
                <Button className="button-theme" size="sm">
                  <i className="bi bi-pencil-fill"/> {I18n.get("view")}
                </Button>
              </Link>
            </td>
          </tr>
        )
      ))
    }
  }

  /**
   * Creates an alert if there are no devices to display
   */
  const emptyDeviceAlert = () => {
    return (
      <Alert
        className="empty-alert"
        variant="secondary"
        show={showAlert}
      >
        <Alert.Heading>
          {I18n.get('no.devices')}
        </Alert.Heading>
        <div>
          <a href='/devices/create'>{I18n.get("create.devices")}</a>&nbsp;{I18n.get("to.get.started")}
        </div>
      </Alert>
    )
  }

  const renderPagination = () => {
    const pageNumbers = Math.ceil(total/10)
    let items = []
    for (let number = 1; number <= pageNumbers; number++) {
      items.push(
        <Pagination.Item key={number} active={number === pageActive} onClick={() => setPageActive(number) }>
          {number}
        </Pagination.Item>,
      );
    }
    return items
  }

  return (
    <div className="page-content">
      <PageTitleBar title={props.title}/>
      <Form
        name="searchForm"
        id="searchForm"
        onSubmit={(event) => {
          handleSubmit(event)
        }}
      >
        <Form.Group>
          <Form.Label>{I18n.get("device.search")}</Form.Label>
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <Form.Control
              as="select"
              id="searchStatus"
              name="searchStatus"
              onChange={(e: any) => setSearchStatus(e.target.value)}
              value={searchStatus}
            >
              <option value="hot">{I18n.get("device.status.select")}</option>
              <option value="cool">{I18n.get("user.created")}</option>
              <option value="warm">{I18n.get("vehicle.demo")}</option>
            </Form.Control>
            <Button
              style={{ marginLeft: '10px' }}
              className="button-theme"
              form="searchForm"
              type="submit">
              Search
            </Button>
          </div>
        </Form.Group>
      </Form>
      <Row>
        <Col>
          <Card className="content-card" style={{ border: '0', marginTop: '20px' }}>
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <Card.Title className="content-card-title" style={{ marginBottom: '0' }}>
              {I18n.get("devices")} ({devices ? devices.length : 0})
            </Card.Title>
            <Button
                style={{ marginLeft: '10px' }}
                className="button-theme header-button"
                size="sm"
                onClick={() => {
                  loadDevices()
                }}
              >
                <i className="bi bi-arrow-repeat"/> {I18n.get("refresh")}
              </Button>
            </div>
            <Card.Body className='content-card-body'>
              <Table className="content-card-table" hover>
                <thead className="table-header">
                <tr>
                  <th></th>
                  <th>{I18n.get("device.thingNames")}</th>
                  <th>{I18n.get("device.status")}</th>
                  <th>{I18n.get("device.temperature")}</th>
                  <th>{I18n.get("actions")}</th>
                </tr>
                </thead>
                <tbody>
                {displayDevices()}
                </tbody>
              </Table>
              <Pagination style={{ justifyContent: 'end' }}>
                <Pagination.First onClick={() => setPageActive(1)} />
                <Pagination.Prev onClick={() => setPageActive(() => pageActive === 1 ? 1 : pageActive - 1)} />
                { renderPagination() }
                <Pagination.Next onClick={() => setPageActive(() => pageActive === Math.ceil(total/10) ? Math.ceil(total/10) : pageActive + 1)} />
                <Pagination.Last onClick={() => setPageActive(Math.ceil(total/10))} />
              </Pagination>
              {emptyDeviceAlert()}
            </Card.Body>
          </Card>
        </Col>
      </Row>
      <Footer pageTitle={props.title}/>
    </div>
  );
}